/*
 * sc_k.c
 *
 * Created: 2012-07-09 07:09:24
 *  Author: Antrykot
 */ 


//#define DEBUG_F

#include "sc-k.h"
#include "utils.h"
#include "trans-k.h"
#include "analog.h"
#include "digital.h" 
//#include "avr/wdt.h"

#include "SWLcd.h"

u16 debug_t[58];

u16 xxx = 0;
u16 yyy = 0;

ISR(INT2_vect)	// pytanie
{
	INT0_DISABLE;
	T0_DISABLE;
	T1_DISABLE;
	T2_DIS;
	t2_timeouts = 0;

	//T1START;
	if (modeftk)
	{
		TS(K_ADDR_KSP,0,0);	// ksp3-pyt
		INT0_ENABLE;
		T0_ENABLE;
		T1_ENABLE;
		return;
	}

	GEN_OFF;
	PLL_LOCK;
	u8 res = respond();
	if (res == 0)
	{
		INT0_ENABLE;
		T1_ENABLE;
		T0_ENABLE;
		T2_ENA;
		return;
	}
	if (res == 1)	/// pilot
	{
		gen_long_pilot();
		INT0_ENABLE;
		T1_ENABLE;
		T0_ENABLE;
		T2_ENA;
		return;
	}		
	if (res == 2)	// normal - with pilot, 
	{
		pilot();	
	}
	// res 3 - special - without pilot  -calib etc.
	GEN_ON;
	PLL_UNLOCK;
	
	u8 wait = 0;

	
	while(!ASKING)
	{
		wait++;
		if (wait > 350)		// 2s timeout
		{
			asknum = 0;
			break;
		}		
	
		
		WAITMS(10);
	}
	PLL_LOCK;
	GEN_OFF; 
	INT0_ENABLE;
	T1_ENABLE;
	T0_ENABLE;
	T2_ENA;

}	

static u8 maximum = MAX_BITS_LONG;

u8 xxxtime = 0;

#define EXIT_INT0_VECTOR { EIFR |= ( 1 << INTF0) ; T1_ENABLE; TIFR1 |= (1 << OCF1A); return;  }

u16 backup_value = 0;

ISR(INT0_vect)
{
	T1_DISABLE;
	logon = 0;

	//PORTB ^= (1 << 5);

	if (modeftk)	// tk
	{
		T2_DIS;
		u16 val = TCNT1;
		TCNT1 = 0;
		T1START;
		
		LY_ON;
		
		if (val > GF0)
		{
			//xxx = bits;
			bits = 0;
			polarity = 0;
			T1STOP;
			TCNT1 = 0;
			T2_ENA;
			EXIT_INT0_VECTOR;
		}
		
		if (!polarity)
		{
			LY_OFF;
			polarity = 1;
			EXIT_INT0_VECTOR;
		}
		else
		{
			LY_OFF;
			trans_f[bits] = val;
			bits++;
			polarity = 0;
			LY_ON;
			LY_OFF;
			EXIT_INT0_VECTOR;
		}
	
	}
	
	else							/// MODE_F _ ALARMS
	{
		if (!polarity)
		{
			TCNT1 = 0;
			T1START;
			polarity = 1;
		}
		else
		{
			if (bits < 5)
			{
				alfreq[bits] = TCNT1;
				
				if (alfreq[bits] > 4000)
				{
					bits = 0;
					polarity = 0;
					T1STOP;
					return;
				}
				bits++;
				polarity = 0;

				T1STOP;
			}
			else
			{
				check_alarms();
				polarity = 0;
				T1STOP;
				bits = 0;
				return;
			}
		}
		
		
	}
	EXIT_INT0_VECTOR;
	
}


u8 dbg_timeout = 0;

ISR(TIMER1_COMPA_vect)		// timeout of 
{
	
	u8 max = 0;
	if (bits >= MAX_BITS_SHORT)
	{
		if (identify(trans_f[1]))
		{
			PORTB &= ~(1 << 7);
			max = MAX_BITS_SHORT;		// 1
			PORTB |= (1 << 7);
		}
		else
		{
			max = MAX_BITS_LONG;		// 0
		}
	}
	else
	{
		swl_clear();
		swl_printi(bits);
		swl_print("bits;");
		swl_proceed();
		
		
		T1STOP;
		TCNT1 = 0;
		bits = 0;
		polarity = 0;
		
		T2_STOP;

		INT0_ENABLE;		
	}

	if (bits < max || !max)
	{
		T1STOP;
		TCNT1 = 0;
		bits = 0;
		polarity = 0;
		
		T2_STOP;

		INT0_ENABLE;
		
	}

	for (u8 c = 0; c < max; c++)
	{
		rbuff[c] = identify(trans_f[c]);
	}
	dig_trans_finish = max;
	PORTB &= ~(1 << 7);
	T2_ENA;

}

ISR(TIMER1_OVF_vect)
{
	
}

u8 t2_timeouts = 0;
u8 no_comm = 0; 
	
ISR(TIMER2_OVF_vect)	// timeout for analog mode
{
	
	t2_timeouts ++;
	
	if (!modeftk)			// KSP-2
	{
		allow_internal_comm = 1;
		if (t2_timeouts > 35)	// 10^-6*1024*255*35 = ~9.5s
		{
			asknum = 0;
			t2_timeouts = 0;
		}
		
	}
	else					// KSP-3
	{
		if (t2_timeouts > 5)	// 10^-6*1024*255*5 = ~1.25s
		{
			t2_timeouts = 5;
			allow_internal_comm = 1;
			logged = 0;
			no_comm ++;
			if (no_comm > 15)
				no_comm = 1;
		}
	}

	
}

int main(void)
{
	GEN_OFF;
	PLL_LOCK;
	 
	
	u8 div = _read(EEP_DIV);
	if (div > 8)
	{
		div = 0;
		_write(EEP_DIV,div);
	}
	WAITMS(30);
	 
	 
	cli();
	CLKPR = (1 << CLKPCE);
	CLKPR = div;		
	
	WAITMS(5);		
	
	init_eeprom();
	setup_io();
	
	set_freq(10400);	
	calc_num();
	
	sei();
	
	ASK_ENABLE;
	INT0_ENABLE;
		
		
	if (!modeftk)
	{
		OCR1A = 10000;
		FTK_SET_F;
	}
	else
	{
		FTK_SET_TK;
		OCR1A = GF0 * 2 ;
	}					
		
	u8 only_short_cnt = 0;			// timeout for being asked while working in KSP-3 MODE
	T2_ENA;

    while(1)
    {
		if (dig_trans_finish == MAX_BITS_LONG)
		{
			INT0_DISABLE;
			no_send = 0;
			
			if (get_digi_trans())		// if it was for me
			{
				no_comm = 0;
				logged = 1;
			}
			bits = 0;
			dig_trans_finish = 0;
			
			only_short_cnt = 0;
			
			T2_ENA;
			sei();
			INT0_ENABLE;
		}	
		
		if (dig_trans_finish == MAX_BITS_SHORT)
		{
			INT0_ENABLE;
			get_short_trans();
			dig_trans_finish = 0;
			allow_internal_comm = 1;
			t2_timeouts = 0;
			bits = 0; 
			no_comm = 0;
			
			trans_s();

			only_short_cnt ++;
			if (only_short_cnt > 12)
			{
				only_short_cnt = 12;
				logged = 0;
			}
			
			sei();
			INT0_ENABLE;
		}	
		
		 
		if (allow_internal_comm )
		{

			allow_internal_comm = 0;

			INT0_DISABLE;			/// disable alarm pulse.

			if (no_comm == 1 && modeftk)
			{
				TS(K_ADDR_NO_COMM,0,0);
			}

			u8 trs_ok = trans_s();


			INT0_ENABLE;	
			if (trs_ok)
			{
			#ifdef MEDIA_FALL
				if ((rs_pom < measurment) || empty_buffer)
				{
					if (rs_pom & (0xC000))
					{
						measurment = rs_pom;
						empty_buffer = 0;
					}
				}
				#else
				if ((rs_pom > measurment) || empty_buffer)
				{
					if (rs_pom & (0xC000))
					{
						measurment = rs_pom;
						empty_buffer = 0;
					}
				}
			#endif
			}
			

		}
		
    }
}


void setup_io()
{
	
	PORTA = 0;
	
	DDRA = 0xFF;	// J10 - J3
	
	
	
	DDRB = 0 | ( 1 << 3);	// FreqTK
	DDRB &= ~( 1 << 2);		// ASK
	
	DDRB |= ( 1 << 7);
	DDRB |= ( 1 << 5);
	
	//DDRB |= (1 << 7);		// green led
	//DDRB |= (1 << 5);		// green led
	DDRB |= (1 << 1);		// sync output
	
	//DDRB |= 0xE0;		// 7,6,5 - leds
	
	PORTB = 0 |  ( 1 << 2);

	PORTC = 0xFF;
	DDRC = ( 0xFC);		// C7-C2	J16 - J11
	

	
	PORTD = 0 | ( 1 << 4) | ( 1 << 3) | (1 << 6) | (1 << 0) | (1 << 1) ;
	
	DDRD = 0 | (1 << 0);		// PILOT
	DDRD |= (1 << 1);			// BLOK_PLL
	DDRD &= ~(1 << 2);			// R_TK
	DDRD |= (1 << 3);			// S_CLK
	DDRD |= (1 << 5);			// S_TX
	DDRD &= ~(1 << 4);			// S_RX
	
	DDRD |= (1 << 6);			// F / TK
	DDRD |= (1 << 7);			// GEN ON/OFF
	
		
	//TR_K_ENABLE;
	//TR_P_ENABLE;
		

	TIMSK0 |= ( 1 << TOIE0);		// interrupt T0 overflow

	TIMSK1 |= ( 1 << OCIE1A);

	
	EICRA = 0 | (1 << ISC21) | (1 << ISC01) ;		// INT0 & INT1 & INT2 falling edge
	
	TCCR2B = 0x07;		// prescaler 1024
	
}

#define EEPROM_FLAG	0xAF

void init_eeprom()
{
	u8 x = _read(0);
	
	if (x != EEPROM_FLAG)
	{
		fkal = OSCCAL;
		nr = 4080;
		write_word(EEP_NR,nr);
		_write(EEP_FKAL,OSCCAL);
		_write(EEP_KSP,0);
		write_word(EEP_RSTCNT,0);		// reset count
		
		leg_date = 12 * 512 + 8 * 32 + 20;
		write_word(EEP_DATE,leg_date);
		
		write_word(EEP_KALDATE,0xAAAA);
		
		write_word(EEP_LRANGE,9000);
		write_word(EEP_HRANGE,11000);
		_write(EEP_KSP_PARAM,0); 
		
		_write(0,EEPROM_FLAG);
	}
	
	nr		= read_word(EEP_NR);
	modeftk = _read(EEP_KSP);
	
	fkal	= _read(EEP_FKAL);
	leg_date = read_word(EEP_DATE);
	
	h_range = read_word(EEP_HRANGE);
	l_range = read_word(EEP_LRANGE);
	ksp_param = _read(EEP_KSP_PARAM);
	
	cli();
	OSCCAL = fkal;
	sei();

}